home *** CD-ROM | disk | FTP | other *** search
/ CU Amiga Super CD-ROM 19 / CU Amiga Magazine's Super CD-ROM 19 (1998)(EMAP Images)(GB)[!][issue 1998-02].iso / CUCD / Programming / LEDA / source / src / plane / _subdivision.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-11-16  |  3.3 KB  |  177 lines

  1. /*******************************************************************************
  2. +
  3. +  LEDA  3.1c
  4. +
  5. +
  6. +  _subdivision.c
  7. +
  8. +
  9. +  Copyright (c) 1994  by  Max-Planck-Institut fuer Informatik
  10. +  Im Stadtwald, 6600 Saarbruecken, FRG     
  11. +  All rights reserved.
  12. *******************************************************************************/
  13.  
  14.  
  15. #include <LEDA/segment.h>
  16. #include <LEDA/subdivision.h>
  17. #include <LEDA/p_dictionary.h>
  18. #include <LEDA/sortseq.h>
  19. #include <LEDA/prio.h>
  20.  
  21. static int compare(segment& s1, segment& s2);
  22.  
  23. typedef p_dictionary<segment,face> strip;
  24.  
  25. typedef p_dictionary<segment,face>* Strip_Ptr;
  26.  
  27. typedef sortseq<double,Strip_Ptr> strip_list;
  28.  
  29. typedef priority_queue<edge,point> X_structure;
  30.  
  31.  
  32.  
  33. static double x_sweep;
  34.  
  35. int compare(segment& s1,segment& s2)
  36. {
  37.   if (s1 == s2) return 0;
  38.  
  39.   double sl1 = s1.slope();
  40.   double sl2 = s2.slope();
  41.  
  42.   if (s1.start() == s2.start()) return compare(sl1,sl2);
  43.  
  44.   if (s1.end() == s2.end()) return compare(sl2,sl1);
  45.  
  46.   double y1 = sl1*x_sweep+s1.y_abs();
  47.   double y2 = sl2*x_sweep+s2.y_abs();
  48.  
  49.   return (y1 > y2) ? 1 : -1;
  50.  
  51. }
  52.  
  53. SubDivision::SubDivision(const graph& G) : planar_map(G)
  54.   edge e;
  55.   segment s;
  56.   point p;
  57.   strip sp;
  58.   int count = 0;
  59.  
  60.   // compute strips
  61.  
  62.   strip_list* strips = new strip_list;
  63.  
  64.   strip_ptr = (void*)strips;
  65.  
  66.   X_structure X;
  67.  
  68.   // initialize X-structure
  69.  
  70.   forall_edges(e,*this) 
  71.   { point p = position(source(e));
  72.     point q = position(target(e));
  73.  
  74.     if (p.xcoord() < q.xcoord()) 
  75.     { X.insert(e,p);
  76.       X.insert(e,q);
  77.      }
  78.    }
  79.  
  80.  
  81.  
  82.  
  83.   // sweep
  84.  
  85.   strip Y;
  86.  
  87.   x_sweep = -MAXDOUBLE;
  88.  
  89.   strips->insert(x_sweep, new strip(Y));    
  90.  
  91.   while( !X.empty() )
  92.   { point    p = X.inf(X.find_min());
  93.     list<edge> L,R;
  94.  
  95.     while ( !X.empty() )
  96.     { pq_item it = X.find_min();
  97.       point    q = X.inf(it);
  98.       edge     e = X.key(it);
  99.  
  100.       if (q != p) break;
  101.  
  102.       if (q == position(source(e)))  // left  end
  103.           L.append(e);    
  104.       else                           // right end
  105.           R.append(e);    
  106.  
  107.       X.del_item(it);
  108.      }
  109.  
  110.  
  111.     // Insert new strip into version List
  112.  
  113.     x_sweep = p.xcoord();
  114.  
  115.     edge e;
  116.     forall(e,R) Y = Y.del(segment(position(source(e)),position(target(e))));
  117.     forall(e,L) Y = Y.insert(segment(position(source(e)),
  118.                                      position(target(e))), adj_face(e));
  119.  
  120.     L.clear();
  121.     R.clear();
  122.  
  123.     strips->insert(x_sweep, new strip(Y));    
  124.  
  125.     }
  126.  
  127.    strips->insert(MAXDOUBLE, new strip(Y));    
  128.  
  129.  
  130.    // compute outer face
  131.  
  132.    seq_item sit = strips->min();
  133.    sit = strips->succ(sit);
  134.  
  135.    outer_face = Y.inf(strips->inf(sit)->min());
  136.  
  137. }
  138.  
  139.  
  140.  
  141. face SubDivision::locate_point(point p) const
  142. {
  143.   strip_list* strips = (strip_list*)strip_ptr;
  144.  
  145.   seq_item sit = strips->locate(p.xcoord()); 
  146.   Strip_Ptr Y = strips->inf(strips->pred(sit));
  147.   x_sweep = p.xcoord();
  148.   p_dic_item it = Y->locate(segment(p,0,1));
  149.   return (it == nil) ? outer_face : Y->inf(it);
  150.  }
  151.  
  152.  
  153. void SubDivision::print_stripes() const
  154. { seq_item it1;
  155.   p_dic_item it2;
  156.   strip_list* strips = (strip_list*)strip_ptr;
  157.  
  158.   forall_items(it1,*strips)
  159.   { Strip_Ptr sp = strips->inf(it1);
  160.     forall_items(it2,*sp) 
  161.       cout << sp->key(it2) << " f = " << int(sp->inf(it2)) << "\n";
  162.     newline;
  163.   }
  164.   newline;
  165.  }
  166.  
  167. SubDivision::~SubDivision() 
  168. { strip_list* strips = (strip_list*)strip_ptr;
  169.   seq_item it;
  170.   forall_items(it,*strips) delete strips->inf(it);
  171.   delete strips; 
  172. }
  173.  
  174.  
  175.